﻿ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chat.Business.Service.BasicHttp;
using VMuktiService;
using Chat.Business.Service.NetP2P;
using Chat.Business.Service.DataContracts;
using VMuktiAPI;


namespace Chat.Presentation
{
    [Serializable]
    public class ChatDummy
    {
        object objHttpChat = null;
        object objNetTcpChat = null;

        public INetTcpChatChannel channelNettcpChat;

        public VMuktiService.BasicHttpServer HttpChatServer = null;

        List<clsMessage> lstMessage = new List<clsMessage>();
        List<string> lstNodes = new List<string>();
        List<string> lstNodesToRemove4GetUserList = new List<string>();
        List<string> lstNodesToRemove4SetUserList = new List<string>();
        

        string UserName;
        int MyId;
        
        int tempcounter = 0;       

        public ChatDummy(string MyName, string UName, int Id, string netP2pUri, string httpUri)
        {
            try
            {               
                UserName = MyName;
                MyId = Id;

                RegHttpServer(httpUri);
                RegNetP2PClient(netP2pUri);

            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "ChatDummy()--:--ChatDummy.cs--:--" + exp.Message + " :--:--");
                ClsException.LogError(exp);
                ClsException.WriteToErrorLogFile(exp);
            }
        }

        void RegHttpServer(object httpUri)
        {
            try
            {
                objHttpChat = new clsHttpChat();
                ((clsHttpChat)objHttpChat).EntsvcJoin += new Chat.Business.Service.BasicHttp.clsHttpChat.delsvcJoin(objHttp_EntsvcJoin);
                ((clsHttpChat)objHttpChat).EntsvcSendMessage += new Chat.Business.Service.BasicHttp.clsHttpChat.delsvcSendMessage(objHttp_EntsvcSendMessage);
                ((clsHttpChat)objHttpChat).EntsvcGetMessages += new Chat.Business.Service.BasicHttp.clsHttpChat.delsvcGetMessages(objHttp_EntsvcGetMessages);
                ((clsHttpChat)objHttpChat).EntsvcGetUserList += new clsHttpChat.delsvcGetUserList(objHttp_EntsvcGetUserList);
                ((clsHttpChat)objHttpChat).EntsvcSetUserList += new clsHttpChat.delsvcSetUserList(objHttp_EntsvcSetUserList);

                ((clsHttpChat)objHttpChat).EntsvcSignOutChat += new clsHttpChat.delsvcSignOutChat(objHttp_EntsvcSignOutChat);
                ((clsHttpChat)objHttpChat).EntsvcUnJoin += new Chat.Business.Service.BasicHttp.clsHttpChat.delsvcUnJoin(objHttp_EntsvcUnJoin);
                HttpChatServer = new BasicHttpServer(ref objHttpChat, httpUri.ToString());
                HttpChatServer.AddEndPoint<Chat.Business.Service.BasicHttp.IHttpChat>(httpUri.ToString());
                HttpChatServer.OpenServer();
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "RegHttpServer()--:--ChatDummy.cs--:--" + exp.Message + " :--:--");
                ClsException.LogError(exp);
                ClsException.WriteToErrorLogFile(exp);
            }
          
        }      

        void RegNetP2PClient(object netP2pUri)
        {
            try
            {
                NetPeerClient npcDummyChat = new NetPeerClient();
                objNetTcpChat = new clsNetTcpChat();
                ((clsNetTcpChat)objNetTcpChat).EntsvcJoin += new clsNetTcpChat.delsvcJoin(DummyClient_EntsvcJoin);
                ((clsNetTcpChat)objNetTcpChat).EntsvcSendMessage += new clsNetTcpChat.delsvcSendMessage(DummyClient_EntsvcSendMessage);
                ((clsNetTcpChat)objNetTcpChat).EntsvcGetUserList += new clsNetTcpChat.delsvcGetUserList(DummyClient_EntsvcGetUserList);
                ((clsNetTcpChat)objNetTcpChat).EntsvcSetUserList += new clsNetTcpChat.delsvcSetUserList(DummyClient_EntsvcSetUserList);
                ((clsNetTcpChat)objNetTcpChat).EntsvcSignOutChat += new clsNetTcpChat.delsvcSignOutChat(DummyClient_EntsvcSignOutChat);
                ((clsNetTcpChat)objNetTcpChat).EntsvcUnJoin += new clsNetTcpChat.delsvcUnJoin(DummyClient_EntsvcUnJoin);
                channelNettcpChat = (INetTcpChatChannel)npcDummyChat.OpenClient<INetTcpChatChannel>(netP2pUri.ToString(), netP2pUri.ToString().Split(':')[2].Split('/')[1], ref objNetTcpChat);

                while (tempcounter < 20)
                {
                    try
                    {
                        channelNettcpChat.svcJoin(UserName);
                        tempcounter = 20;
                    }
                    catch
                    {
                        tempcounter++;
                        System.Threading.Thread.Sleep(1000);
                    }
                }
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "RegNetP2PClient()--:--ChatDummy.cs--:--" + exp.Message + " :--:--");
                ClsException.LogError(exp);
                ClsException.WriteToErrorLogFile(exp);
            }
        }        
        
        #region chat net p2p functions

        void DummyClient_EntsvcJoin(string uName)
        {

        }

        void DummyClient_EntsvcSendMessage(string msg, string from, List<string> to)
        {
            clsMessage objMessage = new clsMessage();
            objMessage.strFrom = from;
            objMessage.lstTo = to;
            objMessage.strMessage = msg;
            lstMessage.Add(objMessage);
        }

        void DummyClient_EntsvcSignOutChat(string from, List<string> to)
        {
            clsMessage objMessage = new clsMessage();
            objMessage.strFrom = from;           
            objMessage.lstTo = to;
            objMessage.strMessage = "SignOut";
            lstMessage.Add(objMessage);
        }

        void DummyClient_EntsvcSetUserList(string uName)
        {
            clsMessage objMessage = new clsMessage();
            objMessage.strFrom = uName;
            //objMessage.lstTo = to;
            objMessage.strMessage = "SetUserList";
            lstMessage.Add(objMessage);
        }

        void DummyClient_EntsvcGetUserList(string uName)
        {
            clsMessage objMessage = new clsMessage();
            objMessage.strFrom = uName;
            //objMessage.lstTo = to;
            objMessage.strMessage = "GetUserList";
            lstMessage.Add(objMessage);
        }        

        void DummyClient_EntsvcUnJoin(string uName)
        {

        }      

        #endregion

        #region chat http server functions

        void objHttp_EntsvcJoin(string uName)
        {
            
            lstNodes.Add(uName);
        }

        void objHttp_EntsvcSendMessage(string msg, string from, List<string> to)
        {            
             channelNettcpChat.svcSendMessage(msg, from, to);
        }

        List<clsMessage> objHttp_EntsvcGetMessages(string recipient)
        {
            List<clsMessage> myMessages = new List<clsMessage>();
            List<int> lstMsgToRemove = new List<int>();

            for (int i = 0; i < lstMessage.Count; i++)
            {
                // lstNodes -- svcJoin
                // lstMsgToRemove -- Those who have received the msg

                if (lstMessage[i].strMessage == "GetUserList" && lstMessage[i].strFrom!=recipient ) 
                {
                    for (int intNodeCnt = 0; intNodeCnt < lstNodes.Count; intNodeCnt++)
                    {
                        if (recipient == lstNodes[intNodeCnt])
                        {
                            myMessages.Add(lstMessage[i]);
                            lstNodesToRemove4GetUserList.Add(recipient);
                            bool isCountOne = false;
                            if (lstNodes.Count == 1)
                            {
                                isCountOne = true;                                
                            }
                            else if (lstNodesToRemove4GetUserList.Count == lstNodes.Count - 1)
                            {
                                isCountOne = true;
                            }
                            if (isCountOne)
                            {
                                lstMsgToRemove.Add(i);
                                lstNodesToRemove4GetUserList.Clear();
                                break; 
                            }
                        }
                    }
                   
                }
                else if (lstMessage[i].strMessage == "SetUserList")
                {
                    for (int intNodeCnt = 0; intNodeCnt < lstNodes.Count; intNodeCnt++)
                    {
                        //if (recipient != lstNodes[intNodeCnt])
                        //{
                        myMessages.Add(lstMessage[i]);
                        if (!lstNodesToRemove4SetUserList.Contains(recipient))
                        {
                            lstNodesToRemove4SetUserList.Add(recipient);
                        }
                        bool isCountOne = false;
                        if (lstNodes.Count == 1)
                        {
                            isCountOne = true;
                        }
                        else if (lstNodesToRemove4SetUserList.Count == lstNodes.Count)
                        {
                            isCountOne = true;
                        }

                        if (isCountOne)
                        {
                            lstMsgToRemove.Add(i);
                            lstNodesToRemove4SetUserList.Clear();
                            break;
                        }
                        //}
                    }

                    //lstMessage.RemoveAt(i);
                    //lstMsgToRemove.Add(i);
                }
                else if (lstMessage[i].strMessage == "SignOut")
                {
                    if (lstMessage[i].lstTo != null)
                    {
                        for (int j = 0; j < lstMessage[i].lstTo.Count; j++)
                        {

                            if (lstMessage[i].lstTo[j] == recipient)
                            {
                                myMessages.Add(lstMessage[i]);
                                lstMessage[i].lstTo.RemoveAt(j);
                                if (lstMessage[i].lstTo.Count == 0)
                                {
                                    //lstMessage.RemoveAt(i);
                                    lstMsgToRemove.Add(i);
                                    break;
                                }
                            }
                        }
                    }
                }



                else 
                {
                    if (lstMessage[i].lstTo != null)
                    {
                        for (int j = 0; j < lstMessage[i].lstTo.Count; j++)
                        {

                            if (lstMessage[i].lstTo[j] == recipient)
                            {
                                myMessages.Add(lstMessage[i]);
                                lstMessage[i].lstTo.RemoveAt(j);
                                if (lstMessage[i].lstTo.Count == 0)
                                {
                                    //lstMessage.RemoveAt(i);
                                    lstMsgToRemove.Add(i);
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            lstMsgToRemove.Reverse();
            foreach (int pointer in lstMsgToRemove)
            {
                lstMessage.RemoveAt(pointer);
            }

            return myMessages;
        }

        void objHttp_EntsvcSetUserList(string uname)
        {
            channelNettcpChat.svcSetUserList(uname);
        }

        void objHttp_EntsvcGetUserList(string uname)
        {
            try
            {
                channelNettcpChat.svcGetUserList(uname);
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "objHttp_EntsvcGetUserList()--:--ChatDummy.cs--:--" + exp.Message + " :--:--");
                ClsException.LogError(exp);
                ClsException.WriteToErrorLogFile(exp);
            }
        }      

        void objHttp_EntsvcSignOutChat(string from, List<string> to)
        {
            channelNettcpChat.svcSignOutChat(from, to);
        }

        void objHttp_EntsvcUnJoin(string uName)
        {
            lstNodes.Remove(uName);
            channelNettcpChat.Close();
        }        

        #endregion
    }
}
